package com.gdty.lic.utils;

import com.gdty.lic.contants.Contants;
import com.gdty.lic.server.AbstractServerInfo;
import com.gdty.lic.vo.LicenseCheckModel;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LicenseUtils {

    public static Map<String,String> generateKeyPair(){
        try {
            Map<String,String> res = new HashMap<>();
            CryptoUtils.AsymmetricKeyPair keyPair = CryptoUtils.generateAsymmetricKeyPair(CryptoUtils.Algorithm.Encryption.RSA_ECB_PKCS1);
            String privateKey = keyPair.getPrivateKey();
            String publicKey = keyPair.getPublicKey();
            res.put("privateKey",privateKey);
            res.put("publicKey",publicKey);
            return res;

        } catch (Exception e) {
            throw new RuntimeException("RSA密钥对生成失败",e);
        }
    }

    public static String generateLicense(Map<String,String> key, LicenseCheckModel model){
        String str = JSONUtils.toJSONString(model);
        StringBuffer sb = new StringBuffer();
        try {
            //公钥签名
            String signature = CryptoUtils.signBySHA256WithRSA(key.get("privateKey"), key.get("publicKey"));
            //密文
            String cipherText = CryptoUtils.encryptByRSAByPri(key.get("privateKey"),str);
            //公钥216位
            sb.append(key.get("publicKey"));
            //签名172位
            sb.append(signature);
            //其他
            sb.append(cipherText);

            return sb.toString();

        }catch (Exception e){
            throw new RuntimeException(MessageFormat.format("证书生成失败：{0}",str),e);
        }

    }

    public static LicenseCheckModel verify(String ciphertext) throws Exception{
        StringBuffer ciphersb = new StringBuffer(ciphertext);
        //
        String pub = ciphersb.substring(0, Contants.pub_length);
        //
        String sign = ciphersb.substring(Contants.pub_length, Contants.sign_length+Contants.pub_length);
        //
        boolean isVerified = CryptoUtils.verifyBySHA256WithRSA(pub, pub, sign);

        if(!isVerified){
            return null;
        }

        //
        String cipher = ciphersb.substring(Contants.sign_length+Contants.pub_length);
        String plainText = CryptoUtils.decryptByRSAByPub(pub, cipher);
        Map cert = JSONUtils.fromJson(plainText, Map.class);

        if(cert==null){
            return null;
        }

        //检验是否本机 - 只要最优MAC地址存在即通过
        AbstractServerInfo local = SystemUtils.getServerInfo();
        boolean isLocalMac = false;
        List<String> m = (List<String>) cert.get("macAddress");
        List<String> macs = local.getMacAddress();
        if(macs!=null&&!macs.isEmpty()){
            for(String mac:macs){
                if(m.contains(mac)){
                    isLocalMac = true;
                    break ;
                }
            }
        }
        if(!isLocalMac){
            return null;
        }
        String cpu = local.getCPUSerial();
        if(!cpu.equals(cert.get("cpuSerial")+"")){
            return null;
        }
        String main = local.getMainBoardSerial();
        if(!main.equals(cert.get("mainBoardSerial")+"")){
            return null;
        }

        //检验过期时间
        long curr = System.currentTimeMillis();
        if(curr>Long.parseLong(cert.get("expireDate")+"")){
            return null;
        }

        return convert(cert);
    }

    private static LicenseCheckModel convert(Map cert){
        LicenseCheckModel model = new LicenseCheckModel();
        model.setCode(cert.get("code")+"");
        model.setCpuSerial(cert.get("cpuSerial")+"");
        model.setMainBoardSerial(cert.get("mainBoardSerial")+"");
        model.setExpireDate(cert.get("expireDate")+"");
        model.setLicenseTo(cert.get("licenseTo")+"");
        model.setLicenseDate(cert.get("licenseDate")+"");
        model.setMacAddress((List<String>)cert.get("macAddress"));
        return model;
    }
}
